//4.1 为什么要有this引用
//先看一个日期的例子
public class Date {
    public int year;
    public int month;
    public int day;

//    this;  //err this只能在成员方法中使用

    public static void main3(String[] args) {
//        System.out.println(this.year);  //err this不能在被static修饰的方法中使用 只能在非静态方法中使用
    }

    //写一个方法 来设置 年月日
    public void setDate(int y, int m, int d) {
        year = y;
        month = m;
        day = d;

//        提出问题:
//        这么多对象，都调用了同一个setDate方法，在这个方法内，是怎么区分是哪个对象调
//        用setDate方法中的year ，month, day?

    }

//   Date this中 this相当于一个隐藏的参数，可以看见，在方法的参数中，加Date this，并没有报错 加Date this，不影响结果

//    Date this传参传递的是隐式参数，如果改为 Date date1 会因为传参个数不相同报错

//    this是“成员方法”第一个隐藏的参数，编译器会自动传递，在成员方法执行时，编译器会负责将调用成员方法
//    对象的引用传递给该成员方法，this负责来接收
    public void printDate(Date this){
        System.out.println(year+"年"+month+"月"+day+"日");
    }
    public static void main1(String[] args) {
        Date date=new Date();
        date.setDate(2004,11,12);
        date.printDate();

        Date date2=new Date();
        date2.setDate(2008,1,8);
        date2.printDate();

        Date date3=new Date();
        date3.setDate(1973,6,3);
        date3.printDate();

        Date date4=new Date();
        date4.setDate(1976,10,4);
        date4.printDate();

    }
//  问题二:形参名不小心与成员变量名相同

//   Date this中 this相当于一个隐藏的参数，可以看见，在方法的参数中，加Date this，并没有报错 加Date this，不影响结果

//    this是“成员方法”第一个隐藏的参数，编译器会自动传递，在成员方法执行时，编译器会负责将调用成员方法
//    对象的引用传递给该成员方法，this负责来接收

//    Date this传参传递的是隐式参数，如果改为 Date date1 会因为传参个数不相同报错
    public void setDate1(Date this,int year, int month, int day) {

//        this只能在成员方法中使用; 在成员方法中 this只能引用当前对象 不能再引用其他对象

//        year = year;
//        month = month;
//        day = day;

//    形参给形参赋值，并没有修改对象中的year month day
//    原因:此时在方法内，year,month,day都是局部变量 此时局部变量优先使用

//        主函数的sout打印的是成员变量，但是在方法的作用域中，是优先使用局部变量，所以相当于自己给自己赋值
//
//        使用this可以解决这个问题

        this.year = year;
        this.month = month;
        this.day = day;
//    解决方案 就是加上this关键字
//    哪个对象的引用 调用了该方法 this就表示哪个引用
    }

    public void printDate1(){
        System.out.println(this.year+"年"+this.month+"月"+this.day+"日");//建议习惯性用this
        this.test(); //第二种用法

//        this的用法有3种:
//        1.可以通过this 访问当前对象的成员变量
//        2.可以通过this 访问当前对象的非静态的成员方法
//        3.可以通过this 访问当前对象的其他构造方法
//        问题:什么是构造方法?

        test();  //不加this也可以 加上更好
    }

//    那函数体中到底是谁给谁赋值?成员变量给成员变量?参数给参数?参数给成员变量?成员变量给参数?
//    估计自己都搞不清楚了。

//   2.三个对象都在调用setDate和printDate函数，但是这两个函数中没有任何有关对象的说明，setDate和
//    printDate函数如何知道打印的是那个对象的数据呢?

    public void test(){
        System.out.println("测试一下test...");
    }

    public static void main(String[] args) {
        Date date=new Date();
        date.setDate1(2004,11,12);
        date.printDate1();

        Date date2=new Date();
        date2.setDate1(2008,1,8);
        date2.printDate();

        Date date3=new Date();
        date3.setDate1(1973,6,3);
        date3.printDate1();

        Date date4=new Date();
        date4.setDate1(1976,10,4);
        date4.printDate1();
    }
    //这次调用的setDate1的结果 和上一次调用setDate的结果完全不同

//    对于给对象赋值：需要调用之前写的SetDate方法才可以将具体的日期设置到对象中。
//    通过上述例子发现两个问题:
//    1.每次对象创建好后调用SetDate方法设置具体日期，比较麻烦，那对象该如何初始化?
//    2.局部变量必须要初始化才能使用，为什么字段声明之后没有给值依然可以使用?
//    通过这两个问题 引出构造方法的讲解
}
